const ipc = require("electron").ipcRenderer;
const shell = require("electron").shell;
const { BrowserWindow } = require("@electron/remote"); // needed to upgrade
const fs = require("fs");
const process = require("child_process");
const server = require("./server");
const package = require("./package");
const install = require("./install");
const path = require("path");

const playBtn = document.getElementById("play");
const settingsBtn = document.getElementById("settings");
const websiteBtn = document.getElementById("web");

const rightSettings = document.getElementById("rightsettings");
const folderBox = document.getElementById("folder");
const browseBtn = document.getElementById("browse");
const fullscanBtn = document.getElementById("fullscan");
const verifyBtn = document.getElementById("verify");
const cancelBtn = document.getElementById("cancel");
const progressBox = document.getElementById("progressbox");
const progressBar = document.getElementById("progress");
const progressText = document.getElementById("progresstext");
const minBtn = document.getElementById("minimize");
const maxBtn = document.getElementById("maximize");
const closeBtn = document.getElementById("close");
const gamesettingsBtn = document.getElementById("gamesettings");
const versionDiv = document.getElementById("version");
versionDiv.innerHTML = "Version 1.0";

const configFile = require("os").homedir() + "/AoW.json";
var config = { folder: "C:\\SwGAoW" };
if (fs.existsSync(configFile)) config = JSON.parse(fs.readFileSync(configFile));
folderBox.value = config.folder;
if (!config.fps) {
  config.fps = 60;
}
if (!config.ram) {
  config.ram = 4096;
}
if (!config.zoom) {
  config.zoom = 1;
}
if (config.multipleInstances === undefined) config.multipleInstances = true;

minBtn.addEventListener(
  "click",
  () => BrowserWindow.getFocusedWindow().minimize() // needed to upgrade
);
maxBtn.addEventListener("click", () => {
  var window = BrowserWindow.getFocusedWindow(); // needed to upgrade
  if (!window.isMaximized()) window.maximize();
  else window.unmaximize();
});
closeBtn.addEventListener(
  "click",
  () => BrowserWindow.getFocusedWindow().close() // needed to upgrade
);

playBtn.addEventListener("click", () => {
  if (playBtn.disabled) return;
  play();
});

function play() {
  var ip = server.address;

  var args = [
    "--",
    "-s",
    "ClientGame",
    "loginServerAddress0=" + ip,
    "loginServerPort0=" + server.port,
    "-s",
    "ClientGame",
    "SetFramesPerSecond=" + config.fps,
    "-s",
    "Station",
    "gameFeatures=34929",
    "-s",
    "SwgClient",
    "allowMultipleInstances=" + (config.multipleInstances ? "true" : "false"),
  ];
  var env = Object.create(require("process").env);
  env.SWGCLIENT_MEMORY_SIZE_MB = config.ram;
  env.DXVK_LOG_LEVEL = "none";
  const child = process.spawn("SWG-AOW.exe", args, {
    cwd: config.folder,
    env: env,
    detached: true,
    stdio: "ignore",
  });
  child.unref();
}

gamesettingsBtn.addEventListener("click", (event) => {
  const child = process.spawn(
    "cmd",
    ["/c", path.join(config.folder, "SWG_Config.exe")],
    { cwd: config.folder, detached: true, stdio: "ignore" }
  );
  child.unref();
});

settingsBtn.addEventListener("click", (event) => {
  if (rightSettings.style.display == "flex") {
    rightSettings.style.display = "none";
    settingsBtn.className = "button";
  } else {
    rightSettings.style.display = "flex";
    settingsBtn.className = "button active";
  }
});

websiteBtn.addEventListener("click", () => shell.openExternal("https://swgaow.duckdns.org/"));

browseBtn.addEventListener("click", function () {
  ipc.send("open-directory-dialog", "selected-directory");
});

folderBox.addEventListener("keyup", (event) => {
  config.folder = event.target.value;
  saveConfig();
  checkPlayReady();
});

ipc.on("selected-directory", function (event, path) {
  folderBox.value = path;
  config.folder = path;
  saveConfig();
  checkPlayReady();
});

const multiInstanceBtn = document.getElementById("multiInstance");

multiInstanceBtn.checked = config.multipleInstances;

multiInstanceBtn.addEventListener("change", function () {
  config.multipleInstances = multiInstanceBtn.checked;
  saveConfig();
});

cancelBtn.addEventListener("click", function (event) {
  install.cancel();
  enableAll();
  checkPlayReady();
  progressBox.style.display = "none";
  currentFileEl.style.display = "none";
});

ipc.on("downloading-update", function (event, text) {
  versionDiv.innerHTML = text;
  disableAll();
});

ipc.on("download-progress", function (event, info) {
  install.progress(info.transferred, info.total);
});

var currentFileEl = document.getElementById("currentfile");
var lastCompleted = 0;
var lastTime = new Date();
var rate = 0;
var units = " B/s";

function checkPlayReady() {
  var exists = fs.existsSync(path.join(config.folder, "SWG-AOW.exe"));
  playBtn.disabled = !exists;
  gamesettingsBtn.disabled = !exists;
}

function resetProgress() {
  lastCompleted = 0;
  lastTime = new Date();
  rate = 0;
}

install.currentFile = function (filename) {
  currentFileEl.innerHTML = filename;
  currentFileEl.style.display = "block";
};

install.progress = function (completed, total) {
  var time = new Date();
  var elapsed = (time - lastTime) / 1000;
  if (elapsed >= 1) {
    var bytes = completed - lastCompleted;
    units = " B/s";
    rate = bytes / elapsed;
    if (rate > 1024) {
      rate = rate / 1024;
      units = " KB/s";
    }
    if (rate > 1024) {
      rate = rate / 1024;
      units = " MB/s";
    }
    lastCompleted = completed;
    lastTime = time;
  }
  if (progressBox.style.display == "none") progressBox.style.display = "block";
  progressText.innerHTML =
    Math.trunc((completed * 100) / total) +
    "% (" +
    rate.toPrecision(3) +
    units +
    ")";
  progressBar.style.width = (completed * 100) / total + "%";
  if (completed == total) {
    enableAll();
    checkPlayReady();
    progressBox.style.display = "none";
    currentFileEl.style.display = "none";
  }
};

install.error = function (msg) {
  progressText.innerHTML = msg.length > 80 ? msg.substr(0, 80) + "..." : msg;
  progressBar.style.width = "0%";
  progressBox.style.display = "block";
  currentFileEl.style.display = "none";
  enableAll();
  checkPlayReady();
};

fullscanBtn.addEventListener("click", function (event) {
  if (fullscanBtn.disabled) return;
  disableAll();
  resetProgress();
  progressText.innerHTML = "Connecting...";
  progressBox.style.display = "block";
  currentFileEl.style.display = "none";
  install.install(config.folder, config.folder, true);
});

verifyBtn.addEventListener("click", function (event) {
  if (verifyBtn.disabled) return;
  disableAll();
  resetProgress();
  progressText.innerHTML = "Connecting...";
  progressBox.style.display = "block";
  currentFileEl.style.display = "none";
  install.install(config.folder, config.folder);
});

checkPlayReady();
settingsBtn.click();

function disableAll() {
  folderBox.disabled = true;
  fullscanBtn.disabled = true;
  verifyBtn.disabled = true;
  playBtn.disabled = true;
  browseBtn.disabled = true;
  gamesettingsBtn.disabled = true;
}

function enableAll() {
  folderBox.disabled = false;
  fullscanBtn.disabled = false;
  verifyBtn.disabled = false;
  browseBtn.disabled = false;
  checkPlayReady();
}

function saveConfig() {
  fs.writeFileSync(configFile, JSON.stringify(config));
}

versionDiv.addEventListener(
  "click",
  () => BrowserWindow.getFocusedWindow().openDevTools() // needed to upgrade
);
